Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
@startupjs/orm
Advanced tools
ORM system for Racer.js and ShareDB
Lets you automatically override your scope models
(created with .at()
and .scope()
) with the additional methods.
Add the plugin:
import Racer from 'racer'
import racerOrm from 'racer-orm'
Racer.use(racerOrm)
Then start adding the ORM entities to your model.
Each ORM Entity must be inherited from Model.ChildModel
.
import { Model } from 'racer'
class PlayerModel extends Model.ChildModel {
alert (message) {
this.set('alert', this.get('name') + ', ' + message)
this.setDiff('showAlert', true)
}
}
class GamesModel extends Model.ChildModel {
async addNew (userId = 'system', params = {}) {
let gameId = this.id()
await this.add('games', {
name: 'Dummy Game',
...params,
id: gameId,
userId,
playerIds: [],
createdAt: Date.now()
})
return gameId
}
}
class GameModel extends Model.ChildModel {
async alertPlayers (message) {
let playerIds = this.get('playerIds')
let playersQuery = this.root.query('players', { _id: { $in: playerIds } })
await this.subscribe(playersQuery)
for (let playerId of playersQuery.getIds()) {
this.scope('players.' + playerId).alert(message)
}
}
async addPlayer (userId, params = {}) {
if (!userId) throw new Error('userId required')
var playerId = this.id()
await this.root.add('players', {
...params,
id: playerId,
userId,
createdAt: Date.now()
})
await this.push('playerIds', playerId)
return playerId
}
}
racer.orm('games', GamesModel)
racer.orm('games.*', GameModel)
racer.orm('players.*', PlayerModel)
// ...
async function main ($root) {
let $games = $root.scope('games')
let gameId = await $games.addNew('userId1', { name: 'Cool game' })
let $game = $games.at(gameId)
for (let userIds of ['userId1', 'userId2', 'userId3']) {
await $game.addPlayer(userIds)
}
$game.alertPlayers('please join the game!')
}
// ...
Sometimes you want to dynamically decide which ORM to use based on the document's data. Factory let you do that.
Example:
class BasePlayerModel extends Model.ChildModel {
getColor () {
throw new Error('Player color is unknown')
}
}
class AlliedPlayerModel extends BasePlayerModel {
getColor () {
return 'blue'
}
}
class RivalPlayerModel extends BasePlayerModel {
getColor () {
return 'red'
}
}
function PlayerFactory ($player, $parent) {
// $player here is going to be just a pure scoped model
let playerTeamId = $player.get('teamId')
let $root = $player.root
let myTeamId = $root.get('_session.myTeamId')
// you have to always pass `$parent` when manually
// instantiating the ORM Entity
if (!playerTeamId || !myTeamId) return new BasePlayerModel($parent)
if (playerTeamId === myTeamId) {
return new AlliedPlayerModel($parent)
} else {
return new RivalPlayerModel($parent)
}
}
PlayerFactory.factory = true
racer.orm('players.*', PlayerFactory)
You can optionally specify an alias for the ORM Entity:
racer.orm('players.*', PlayerModel, 'Player')
This will allow you to explicitly specify in .at()
and .scope()
which ORM Entity to use even for the unknown path patters:
let playerId = 'playerId1'
// will create the PlayerModel, since it matches the specified path pattern:
model.scope('players.' + playerId).alert('please join the game!')
// The following will also create the PlayerModel
// even though '_session.myPlayer' wasn't specified in the orm path patterns:
model.scope('_session.myPlayer', 'Player').alert('please join the game!')
IMPORTANT: Note, that this is a bad practice and must only be used in the edge cases.
It's always better to list all your path patterns explicitly and don't use aliases at all:
racer.orm('players.*', PlayerModel)
racer.orm('_session.myPlayer', PlayerModel)
racer.orm('_session.rivalPlayer', PlayerModel)
server/index.js
add validateSchema: true
to startupjsServer()
optionsUserModel
, which targets users.*
) and add a static method schema
:import { BaseModel } from 'startupjs/orm'
export default class UserModel extends BaseModel {
static schema = {
firstName: { type: 'string' },
lastName: { type: 'string' },
age: {
type: 'number',
multipleOf: 1,
minimum: 0,
maximum: 130
}
}
}
NODE_ENV
is production
<collection>.*
are gonna be parsed for schema
definitions.MIT
(c) Decision Mapper - http://decisionmapper.com
FAQs
ORM system for Racer.js and ShareDB
We found that @startupjs/orm demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.